//*******************************************************************       //
//IMPORTANT NOTICE                                                          //
//================                                                          //
//Copyright Mentor Graphics Corporation 1996 - 1999.  All rights reserved.  //
//This file and associated deliverables are the trade secrets,              //
//confidential information and copyrighted works of Mentor Graphics         //
//Corporation and its licensors and are subject to your license agreement   //
//with Mentor Graphics Corporation.                                         //
//                                                                          //
//Use of these deliverables for the purpose of making silicon from an IC    //
//design is limited to the terms and conditions of your license agreement   //
//with Mentor Graphics If you have further questions please contact Mentor  //
//Graphics Customer Support.                                                //
//                                                                          //
//This Mentor Graphics core (m8051w v2002.080) was extracted on             //
//workstation hostid 8316cbec Inventra                                      //
// 8x8-bit multiplier and divider for M8051W/EW
// 
// $Log: m3s005dy.v,v $
// Revision 1.6  2002/03/13
// changed code to be the same with VHDL, the signal STATE0 changed
//
// Revision 1.5  2001/11/20
// First checkin of version 2 features and name change
//
// Revision 1.2  2001/10/31
// First parsable verilog for EW
//
// Revision 1.1.1.1  2001/07/17
// Re-imported E-Warp from Farnham filesystem
//
// Revision 1.4  2000/10/24
// Multiplier rewritten to improve power consumption.
// Code changes for Leonardo (ECN01372).
// Code changes for formal verification tools (ECN01410).
// MOVX @Ri page address controllable from PORT2I if I/O ports ommitted (ECN01387).
//
// Revision 1.3  2000/02/05
// Name change repercussions
//
// Revision 1.2  1999/11/30
// More debug changes.
//
// Revision 1.1.1.1  1999/10/28
// "initialization and source check-in for m8051e"
//
// Revision 1.1  1999/10/22
// Initial revision
//
////////////////////////////////////////////////////////////////////////////////

module m3s005dy(RESULT_A, RESULT_B, RESULT_OV, ACC, B, STATE, CCLK, MULNDIV,
//*******************************************************************       //
//IMPORTANT NOTICE                                                          //
//================                                                          //
//Copyright Mentor Graphics Corporation 1996 - 1999.  All rights reserved.  //
//This file and associated deliverables are the trade secrets,              //
//confidential information and copyrighted works of Mentor Graphics         //
//Corporation and its licensors and are subject to your license agreement   //
//with Mentor Graphics Corporation.                                         //
//                                                                          //
//Use of these deliverables for the purpose of making silicon from an IC    //
//design is limited to the terms and conditions of your license agreement   //
//with Mentor Graphics If you have further questions please contact Mentor  //
//Graphics Customer Support.                                                //
//                                                                          //
//This Mentor Graphics core (m8051w v2002.080) was extracted on             //
//workstation hostid 8316cbec Inventra                                      //
                INTERNAL_WAIT, ENABLE);
  output  [7:0]   RESULT_A;	  // Accumulator Result
  output  [7:0]   RESULT_B;	  // B Register Result
  output          RESULT_OV;      // Overflow flag result

  input   [7:0]   ACC, B;   	  // Operands
  input           MULNDIV;        // Opcode
  input           INTERNAL_WAIT;  // suspend CPU activity
  input           ENABLE;         // enable block
  input   [2:0]   STATE;
  input           CCLK;

  wire            STATE0;
  wire    [2:0]   Q_STATE;
  wire    [14:0]  SUB_DENOM;
  wire    [7:0]   SUB_DIVID;
  wire    [7:0]   REMAINDER;
  wire    [8:0]   NEXT_REMAINDER;
  wire            VULGAR;
  wire    [15:0]  NEXT_PRODUCT;
  wire    [7:0]   NEXT_DIVIDEND;

  reg     [15:0]  SUB_PRODUCT;

  assign Q_STATE = STATE & {3{ENABLE}};

  // Conditional 9-bit adder used for multiplication

  assign NEXT_PRODUCT[15:7] = SUB_PRODUCT[15:8] + ({8{ACC[Q_STATE]}} & B);
  assign NEXT_PRODUCT[6:0]  = SUB_PRODUCT[7:1];
//------------------------------------------------------------------------------------
// The formalpro Tool provided diffrences because of the logic below
//------------------------------------------------------------------------------------
//assign STATE0   = ~|Q_STATE; // The Verilog Contained this logic
  assign STATE0   = ~|STATE; // The VHDL contains this logic, the VHDL is the Master fileset
//------------------------------------------------------------------------------------  
  // SUB_DENOM is B multiplied by two raised to the power of the ones complement
  // of the STATE number.

  assign SUB_DENOM = {7'h00, B} << (~Q_STATE);

  // Current remainder for division

  assign REMAINDER = SUB_PRODUCT[15:8] | {8{STATE0}} & ACC;

  // 9-bit subtractor used for division

  assign NEXT_REMAINDER = {1'b1, REMAINDER} - {1'b0, SUB_DENOM[7:0]};

  // VULGAR indicates that the current remainder is larger than the current 
  // denominator and requires further subtraction to avoid a vulgar fraction.

  assign VULGAR    = NEXT_REMAINDER[8] & ~|SUB_DENOM[14:8];

  // SUB_DIVID contains the current component of the dividend to be added to the
  // accumulated dividend.

  assign SUB_DIVID = {7'h00, VULGAR} << (~Q_STATE);

  assign NEXT_DIVIDEND  = SUB_PRODUCT[7:0] | SUB_DIVID;

  // Multiplier/divider output multiplexer

  assign RESULT_B  = MULNDIV? NEXT_PRODUCT[15:8]: (VULGAR? NEXT_REMAINDER[7:0]:
                                                           REMAINDER);
  assign RESULT_A  = MULNDIV? NEXT_PRODUCT[7:0]:   NEXT_DIVIDEND[7:0];
  assign RESULT_OV = MULNDIV? |NEXT_PRODUCT[15:8]: ~|B;
			 
  // Temporary storage for partial results
			 
  always @(posedge CCLK)
  begin: p_mul_temp
    if (~INTERNAL_WAIT)
      if (&STATE | !ENABLE)
        SUB_PRODUCT <= 0;
      else
        SUB_PRODUCT <= {RESULT_B, RESULT_A};
  end
			 
endmodule
